package com.test.A39;

import java.lang.reflect.Constructor;
import java.util.List;

import org.springframework.boot.DefaultBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.support.SpringFactoriesLoader;


public class A39_2 {

	public static void main(String[] args) throws Exception {
		test2(args);
	}

	
	/** 
	 * 获取事件发送器   SpringApplicationRunListener
	 * @param args
	 * @throws Exception
	 */
	private static void test1(String[] args) throws Exception {
        SpringApplication app = new SpringApplication();
        app.addListeners(e -> System.out.println(e.getClass()));// 添加 app 监听器   得到发布器的类名

        // 获取事件发送器实现类名
        List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A39_2.class.getClassLoader());
        //事件接收器 SpringApplicationRunListener
        for (String name : names) {
            System.out.println(name);
        }
		
	}
	
	
	/***
	 * 发布器发布事件
	 * @param args
	 * @throws Exception
	 */
	private static void test2(String[] args) throws Exception {
		 // 添加 app 监听器
        SpringApplication app = new SpringApplication();
        app.addListeners(e -> System.out.println(e.getClass()));// 添加 app 监听器   得到发布器的类名

        // 获取事件发送器实现类名
        List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A39_2.class.getClassLoader());
        for (String name : names) {
            System.out.println(name);
            Class<?> clazz = Class.forName(name);
            Constructor<?> constructor = clazz.getConstructor(SpringApplication.class, String[].class);  //通过构造得到构造器    没有无参构造
            SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(app, args);//创建发布器对象

            // 发布事件
            DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
            publisher.starting(bootstrapContext); // spring boot 开始启动
            publisher.environmentPrepared(bootstrapContext, new StandardEnvironment()); // 环境信息准备完毕
            GenericApplicationContext context = new GenericApplicationContext();
            publisher.contextPrepared(context); // 在 spring 容器创建，并调用初始化器之后，发送此事件
            publisher.contextLoaded(context); // 所有 bean definition 加载完毕
            context.refresh();
            publisher.started(context); // spring 容器初始化完成(refresh 方法调用完毕)
            publisher.running(context); // spring boot 启动完毕
            publisher.failed(context, new Exception("出错了")); // spring boot 启动出错
	   }
	
	}
	
	
}
